package org.bronycorps.mlptss.manager;

import java.util.ArrayList;

import org.bronycorps.mlptss.manager.preferences.AnimationConfiguration;
import org.bronycorps.mlptss.manager.preferences.AssetsConfiguration.CharacterConfiguration;
import org.bronycorps.mlptss.manager.preferences.GameConfiguration;
import org.bronycorps.mlptss.manager.preferences.ModConfiguration.AnimatedBackgroundConfig;
import org.bronycorps.mlptss.manager.preferences.ModConfiguration.BackgroundConfig;
import org.bronycorps.mlptss.utils.AnimationCache;
import org.bronycorps.mlptss.utils.DrawableAnimation;

import com.badlogic.gdx.assets.AssetManager;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.g2d.BitmapFont;
import com.badlogic.gdx.graphics.g2d.TextureAtlas;
import com.badlogic.gdx.graphics.g2d.TextureAtlas.AtlasRegion;
import com.badlogic.gdx.math.Rectangle;
import com.badlogic.gdx.math.Vector2;
import com.badlogic.gdx.scenes.scene2d.ui.Skin;
import com.badlogic.gdx.utils.Array;

public class CommonAssetManager {

	private static CommonAssetManager instance = null;

	public static CommonAssetManager getInstance() {
		if (instance == null) {
			instance = new CommonAssetManager();
		}
		return instance;
	}

	private final AssetManager assetManager;
	private GameConfiguration configuration;

	private CommonAssetManager() {
		this.configuration = GameConfiguration.getInstance();

		this.assetManager = new AssetManager();

		// game fonts
		this.assetManager.load(this.configuration
				.convertPath(this.configuration.getCurrentMod().getFontFile()),
				BitmapFont.class);
		this.assetManager.load(this.configuration
				.convertPath(this.configuration.getCurrentMod().getMenuConfig()
						.getCharacterNameFont()), BitmapFont.class);

		// HUD
		this.assetManager.load(this.configuration
				.convertPath(this.configuration.getCurrentMod()
						.getHudLifeAtlas()), TextureAtlas.class);
		this.assetManager.load(this.configuration
				.convertPath(this.configuration.getCurrentMod()
						.getHudMidWallFile()), Texture.class);

		// menu
		this.assetManager
				.load(this.configuration.convertPath(this.configuration
						.getCurrentMod().getMenuConfig().getSkin()), Skin.class);
		this.assetManager.load(
				this.configuration.convertPath(this.configuration
						.getCurrentMod().getMenuConfig().getBackground()),
				Texture.class);
		this.assetManager.load(this.configuration
				.convertPath(this.configuration.getCurrentMod().getMenuConfig()
						.getDefaultBackground()), Texture.class);
		this.assetManager.load(
				this.configuration.convertPath(this.configuration
						.getCurrentMod().getMenuConfig().getMenuItems()),
				TextureAtlas.class);
		this.assetManager.load(
				this.configuration.convertPath(this.configuration
						.getCurrentMod().getMenuConfig().getGameOverAtlas()),
				TextureAtlas.class);

		// level background
		for (AnimatedBackgroundConfig abgConf : this.configuration
				.getCurrentMod().getBackgrounds()) {
			for (BackgroundConfig bgConf : abgConf.getBackgrounds()) {
				this.assetManager.load(
						this.configuration.convertPath(bgConf.getPath()),
						Texture.class);

			}
		}

		for (String atlasPath : this.configuration.getCurrentMod()
				.getAssetsConfiguration().getAllAtlases()) {
			this.assetManager.load(this.configuration.convertPath(atlasPath),
					TextureAtlas.class);
		}

		loadCharacterAssets();

	}

	private void createAnimation(String animationName, String pathName,
			String regionName, float frameDuration, int animationMode,
			Vector2 origin, Rectangle bounds) {
		TextureAtlas atlas = this.assetManager.get(
				this.configuration.convertPath(pathName), TextureAtlas.class);
		Array<AtlasRegion> frames = atlas.findRegions(regionName);
		DrawableAnimation drawAnim = new DrawableAnimation(frameDuration,
				frames, animationMode, origin, bounds);

		AnimationCache.getInstance().put(animationName, drawAnim);
	}

	private void createAnimations() {
		for (AnimationConfiguration config : this.configuration.getCurrentMod()
				.getAssetsConfiguration().getAnimations()) {
			createAnimation(config.getAnimationName(), config.getPathName(),
					config.getRegionName(), config.getFrameDuration(),
					config.getAnimationMode(), config.getOrigin(),
					config.getBounds());
		}
	}

	public void finishLoading() {
		this.assetManager.finishLoading();

		createAnimations();
	}

	public <T> T get(String fileName, Class<T> type) {
		return this.assetManager.get(fileName, type);
	}

	public String getScriptPath(String name) {
		return "script/" + name;
	}

	private void loadCharacterAssets() {
		ArrayList<CharacterConfiguration> characters = this.configuration
				.getCurrentMod().getAssetsConfiguration().getCharacters();
		for (CharacterConfiguration characterConfiguration : characters) {
			this.assetManager.load(this.configuration
					.convertPath(characterConfiguration.getAssetAtlas()),
					TextureAtlas.class);
		}
	}
}
